package com.fzu.geometa.metadata.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzu.geometa.metadata.mapper.NamespaceMapper;
import com.fzu.geometa.metadata.model.po.Item;
import com.fzu.geometa.metadata.model.po.Namespace;
import com.fzu.geometa.metadata.model.po.Register;
import com.fzu.geometa.metadata.service.ItemService;
import com.fzu.geometa.metadata.service.NamespaceService;
import com.fzu.geometa.metadata.service.RegisterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* @author DaleLee
* @description 针对表【namespace(命名空间表)】的数据库操作Service实现
* @createDate 2023-02-22 16:29:03
*/
@Service
@Transactional
public class NamespaceServiceImpl extends ServiceImpl<NamespaceMapper, Namespace>
    implements NamespaceService{
    @Autowired
    ItemService itemService;
    @Autowired
    RegisterService registerService;

    // 不能被删除的 ns
    private static final Set<String> excludedNamespace = new HashSet<>();

    static {
        excludedNamespace.add("xsi");
    }

    @Override
    public List<Namespace> listByCid(Long cid) {
        LambdaQueryWrapper<Namespace> nsLQW = new LambdaQueryWrapper<>();
        nsLQW.eq(Namespace::getCid, cid);
        return this.list(nsLQW);
    }

    @Override
    public boolean removeByCid(Long cid) {
        LambdaQueryWrapper<Namespace> nsLQW = new LambdaQueryWrapper<>();
        nsLQW.eq(Namespace::getCid, cid);
        return this.remove(nsLQW);
    }

    @Override
    public boolean removeBatchByCid(List<Long> ids) {
        LambdaUpdateWrapper<Namespace> luw = new LambdaUpdateWrapper<>();
        luw.in(Namespace::getCid,ids);
        return remove(luw);
    }

    @Override
    public boolean safelyRemove(Long id) {
        Namespace ns = getById(id);
        if (ns == null) {
            return false;
        }

        if (excludedNamespace.contains(ns.getPrefix())) {
            return false;
        }

        // 如果正在使用，则不能删除
        List<Item> list = getItemsByPrefix(ns.getCid(),ns.getPrefix());
        if (list == null || list.size() == 0) {
            return removeById(id);
        } else {
            return false;
        }
    }

    @Override
    public boolean safelyUpdate(Namespace namespace) {
        if (namespace == null) {
            return false;
        }
        Namespace ns = getById(namespace.getId());
        if (ns == null) {
            return false;
        }

        // 可以只更新 uri
        if (ns.getPrefix().equals(namespace.getPrefix())) {
            return updateById(namespace);
        }

        List<Item> list = getItemsByPrefix(ns.getCid(),ns.getPrefix());
        if (list == null || list.size() == 0) {
            return updateById(namespace);
        } else {
            return false;
        }

    }

    @Override
    public boolean safelyAdd(Namespace namespace) {
        if (namespace == null) {
            return false;
        }
        // 被添加的数据集必须存在，不能添加到一个不存在的数据集上
        Register register = registerService.getById(namespace.getCid());
        if (register == null) {
            return false;
        }
        LambdaQueryWrapper<Namespace> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Namespace::getCid,namespace.getCid())
                .eq(Namespace::getPrefix,namespace.getPrefix());
        Namespace ns = getOne(lqw);
        // 不能添加重复的前缀
        if (ns != null && ns.getPrefix().equals(namespace.getPrefix())) {
            return false;
        } else {
            return save(namespace);
        }
    }

    @Override
    public boolean isValidNamespace(Long cid, String namespace) {
        if (StringUtils.isBlank(namespace)) {
            // 空 namespace 允许添加
            return true;
        }
        // 判断该 namespace 是否存在
        LambdaQueryWrapper<Namespace> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Namespace::getCid,cid)
                .eq(Namespace::getPrefix,namespace);
        Namespace ns = getOne(lqw);
        return ObjectUtil.isNotNull(ns);
    }

    private List<Item> getItemsByPrefix(Long cid, String prefix) {
        LambdaQueryWrapper<Item> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Item::getCid, cid)
                .eq(Item::getNamespace,prefix);
        return itemService.list(lqw);
    }
}




